package com.ruoyi.asms.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Sets;
import com.ruoyi.ams.controller.AmsAssetTypeController;
import com.ruoyi.ams.controller.AmsOwnAddressController;
import com.ruoyi.asms.domain.*;
import com.ruoyi.asms.domain.vo.*;
import com.ruoyi.asms.service.*;
import com.ruoyi.asms.util.InspectionExcelUtil;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsAssetType;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.BusinessUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.security.service.TokensService;
import com.ruoyi.file.controller.SysFileController;
import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 巡检信息Controller
 *
 * @author yfkj
 * @date 2021-10-21
 */
@RestController
@RequestMapping("/asms/Inspection")
public class InspectionController extends BaseController {
    @Autowired
    private IInspectionService inspectionService;
    @Autowired
    private IAsmsOwnAddressAssetCodeService asmsOwnAddressAssetCodeService;

    @Autowired
    private IAsmsFaultService asmsFaultService;
    @Autowired
    private IFaultInfoViewService faultInfoViewService;
    @Autowired
    private IAsmsFaultReportStageService asmsFaultReportStageService;
    @Autowired
    private IAsmsFaultDispatchStageService asmsFaultDispatchStageService;
    @Autowired
    private IAsmsFaultConfirmStageService asmsFaultConfirmStageService;
    @Autowired
    private IAsmsFaultFeedbackStageService asmsFaultFeedbackStageService;
    @Autowired
    private IAsmsFaultAssetReasonService asmsFaultAssetReasonService;
    @Autowired
    private IAsmsMaintenanceChargeInfoService asmsMaintenanceChargeInfoService;
    @Autowired
    private IAsmsMaintenanceAssetService asmsMaintenanceAssetService;
    @Autowired
    private IAsmsFaultResolveStageService asmsFaultResolveStageService;
    @Autowired
    private IAsmsOwnChargeInfoService asmsOwnChargeInfoService;
    @Autowired
    private TokensService tokenService;

    @Autowired
    private AsyncService asyncService;
    @Autowired
    private IInspectionTaskService inspectionTaskService;
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
    @Autowired
    private IAsmsFaultAssetService asmsFaultAssetService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteFileService remoteFileService;
//    @Autowired
//    private RemoteAssetTypeService remoteAssetTypeService;
//    @Autowired
//    private RemoteAssetAddressService remoteAssetAddressService;
    @Autowired
    private SysDeptController deptController;
    @Autowired
    private SysUserController userController;
    @Autowired
    private SysFileController fileController;
    @Autowired
    private AmsAssetTypeController assetTypeController;
    @Autowired
    private AmsOwnAddressController ownAddressController;

    @GetMapping("/getInspectionList")
    @ApiOperation("获取巡检记录列表")
    public TableDataInfo getInspectionList(Inspection inspection){
        //维护商
        Set<Long> userCanLookDeptIds = new HashSet<>();

        SerializeConfig serializeConfig=new SerializeConfig();
        serializeConfig.propertyNamingStrategy= PropertyNamingStrategy.SnakeCase;
        String json = JSON.toJSONString(inspection, serializeConfig);
        Map map = JSONObject.parseObject(json, Map.class);
        map.remove("params");
        List<InspectionTask> inspectionTaskList = new ArrayList<>();

        if(SecurityUtils.getUserId()!=1){
            userCanLookDeptIds=tokenService.getUserCanLookDeptIds();
            if(userCanLookDeptIds==null||userCanLookDeptIds.size()==0){
                return getDataTable(new ArrayList<>(0));
            }
            inspectionTaskList=inspectionTaskService.list(new QueryWrapper<InspectionTask>().
                    in(InspectionTask.MAINTENANCE_DEPT_ID, userCanLookDeptIds));
        }else {
            inspectionTaskList=inspectionTaskService.list();
        }
        Map<Long, InspectionTask> taskMap = new HashMap<>();
        for(InspectionTask task : inspectionTaskList){
            taskMap.put(task.getInspectionTaskId(),task);
            if(SecurityUtils.getUserId()!=1){
                userCanLookDeptIds.addAll(Sets.newHashSet(Convert.toLongArray(task.getAssetOwnIds())));
            }
        }
        if(taskMap.size() < 1){
            TableDataInfo tableDataInfo = new TableDataInfo();
            tableDataInfo.setCode(200);
            tableDataInfo.setMsg("未找到巡检记录");
            return tableDataInfo;
        }
        QueryWrapper<Inspection> queryWrapper = new QueryWrapper<Inspection>()
                .in(Inspection.INSPECTION_TASK_ID,taskMap.keySet())
                .orderByDesc(Inspection.CREATE_TIME);
        if(inspection.getInspectionUserId()!=null){
            queryWrapper.eq(Inspection.INSPECTION_USER_ID,inspection.getInspectionUserId());
        }
        if(inspection.getStatus()!=null){
            queryWrapper.eq(Inspection.STATUS,inspection.getStatus());
        }
        if(inspection.getInspectionId()!=null){
            queryWrapper.eq(Inspection.INSPECTION_ID,inspection.getInspectionId());
        }
        if(inspection.getResultType()!=null){
            queryWrapper.eq(Inspection.RESULT_TYPE,inspection.getResultType());
        }

        startPage();
        List<Inspection> list = inspectionService.list(queryWrapper);
        Set<Long> userIdSet =new HashSet<>();
        Map<Long, SysDept> deptMap =new HashMap<>();
        if(SecurityUtils.getUserId()==1){
            R<List<SysDept>> deptList = deptController.getDeptList();
            BusinessUtils.checkRemoteService(deptList);
            deptMap=deptList.getData().stream().collect(Collectors.toMap(SysDept::getDeptId, item->item));
        }else {
            R<Map<Long, SysDept>> rDeptMap = deptController.getDeptNameAndManegerByDeptIds(new ArrayList<>(userCanLookDeptIds));
            if(R.FAIL ==rDeptMap.getCode()){
                throw new ServiceException(rDeptMap.getMsg());
            }
            deptMap=rDeptMap.getData();
        }

        HashMap<Long, AmsAssetType> assetTypeMap = new HashMap<>(32);
        HashMap<Long, SysUser> userMap = new HashMap<>(32);
        List<InspectionInfoVo> vos = new LinkedList<>();
        Set<Long> addressIds =new HashSet<>();
        Set<Long> assetIds =new HashSet<>();
        Set<Long> faultIds =new HashSet<>();
        Set<Long> userIds =new HashSet<>();
        for(Inspection in : list) {
            addressIds.add(in.getAddressId());
            assetIds.add(in.getAssetId());

            if(in.getFaultId() != null){
                faultIds.add(in.getFaultId());
            }

            if(in.getInspectionUserId() != null){
                userIds.add(in.getInspectionUserId());
            }

        }
        QueryWrapper<AsmsOwnAddressAssetCode> wrapper = new QueryWrapper<>();
        if (addressIds.size() > 0) {
            wrapper.in(AsmsOwnAddressAssetCode.ADDRESS_ID, addressIds)
                    .select(AsmsOwnAddressAssetCode.CODE, AsmsOwnAddressAssetCode.ADDRESS_ID);
        }
        List<AsmsOwnAddressAssetCode> codeList = asmsOwnAddressAssetCodeService.list(wrapper);
        Map<Long, List<AsmsOwnAddressAssetCode>> addressIdAddressCodeMap =new HashMap<>();
        if(codeList.size()>0){
            addressIdAddressCodeMap=codeList.stream().collect(Collectors.groupingBy(AsmsOwnAddressAssetCode::getAddressId, Collectors.toList()));
        }
        R<Map<Long, AmsOwnAddress>> rAddress = ownAddressController.getAddressByIds(addressIds.toArray(new Long[0]));
        BusinessUtils.checkRemoteService(rAddress);
        List<AsmsAssetFullInfo> assetList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>().
                in(assetIds.size()>0, AsmsAssetFullInfo.ASSET_ID, assetIds));
        Map<Long, AsmsAssetFullInfo> assetIdAssetMap = new HashMap<>();
        if(assetList.size()>0){
            assetIdAssetMap=assetList.stream().collect(Collectors.toMap(AsmsAssetFullInfo::getAssetId, item->item));
        }
        Map<Long, AsmsFaultResolveStage> faultIdFaultResolveStageMap =new HashMap<>();
        if(faultIds.size()>0){
            List<AsmsFaultAsset> faultAssets = asmsFaultAssetService.list(new QueryWrapper<AsmsFaultAsset>().
                    in(AsmsFaultAsset.FAULT_ID, faultIds));
            Set<Long> faultAssetIds =new HashSet<>();

            Map<Long, Long> faultAssetIdFaultIdMap =new HashMap<>();
            if(faultAssets.size()>0){
                faultAssetIds = faultAssets.stream().map(AsmsFaultAsset::getFaultAssetId).collect(Collectors.toSet());
                faultAssetIdFaultIdMap = faultAssets.stream().collect(Collectors.toMap( AsmsFaultAsset::getFaultAssetId, AsmsFaultAsset::getFaultId));
            }

            List<AsmsFaultResolveStage> asmsFaultResolveStages = new ArrayList<>();
            QueryWrapper<AsmsFaultResolveStage> queryWrapper1 = new QueryWrapper<>();
            if (faultAssetIds.size() > 0) {
                queryWrapper1.in(AsmsFaultResolveStage.FAULT_ASSET_ID, faultAssetIds);
                asmsFaultResolveStages = asmsFaultResolveStageService.list(queryWrapper1);

            }
            if(asmsFaultResolveStages.size()>0){
                Map<Long, AsmsFaultResolveStage> result = new HashMap<>();
                for (AsmsFaultResolveStage item : asmsFaultResolveStages) {
                    if (result.put(faultAssetIdFaultIdMap.get(item.getFaultAssetId()), item) != null) {
                        Long aLong = faultAssetIdFaultIdMap.get(item.getFaultAssetId());
                        throw new IllegalStateException("Duplicate key");
                    }
                }
                faultIdFaultResolveStageMap = result;
            }

        }
        R<Map<Long, SysUser>> rUserList = userController.getUserListByIds(userIds.toArray(new Long[0]));
        BusinessUtils.checkRemoteService(rUserList);
        for(Inspection in : list) {
            InspectionInfoVo vo = new InspectionInfoVo();
            BeanUtils.copyProperties(in, vo);
            vo.setInspectionTaskName(taskMap.get(vo.getInspectionTaskId()).getInspectionTheme());
            String codes ="";
            userIdSet.add(vo.getInspectionUserId());
            if (vo.getAddressId() != null) {
                vo.setAddressFullName(rAddress.getData().get(in.getAddressId()).getFullName());
                for (AsmsOwnAddressAssetCode code : addressIdAddressCodeMap.get(in.getAddressId())) {
                    codes=codes+code.getCode()+";";
                }
            }
            vo.setCodes(codes);
            if (vo.getAssetId() != null&&assetIdAssetMap.get(vo.getAssetId())!=null) {
                vo.setAssetTypeName(assetIdAssetMap.get(vo.getAssetId()).getAssetTypeName());
                vo.setAssetTypeId(assetIdAssetMap.get(vo.getAssetId()).getAssetTypeId());
            }
            if (vo.getFaultId() != null) {
                if (faultIdFaultResolveStageMap.get(in.getFaultId()) != null) {
                    AsmsFaultResolveStage resolveStage = faultIdFaultResolveStageMap.get(in.getFaultId());
                    vo.setAssetFaultReason(resolveStage.getAssetFaultReason());
                    vo.setAssetFaultReasonId(resolveStage.getAssetFaultReasonId());
                    vo.setAssetFaultSolution(resolveStage.getAssetFaultSolution());
                    vo.setResolveType(resolveStage.getResolveType());
                    vo.setFaultType(resolveStage.getFaultType());
                }
            }
            if (deptMap.containsKey(in.getOwnDeptId())) {
                vo.setOwnDeptName(deptMap.get(in.getOwnDeptId()).getDeptShortName());
                vo.setOwnDeptUserName(deptMap.get(in.getOwnDeptId()).getLeader());
                vo.setOwnDeptUserPhone(deptMap.get(in.getOwnDeptId()).getPhone());
            }
            if(vo.getInspectionUserId() != null){
                if(!userMap.containsKey(vo.getInspectionUserId())){
                    SysUser user = rUserList.getData().get(vo.getInspectionUserId());
                    if(user != null){
                        userMap.put(vo.getInspectionUserId(),user);
                    }else{
                        userMap.put(vo.getInspectionUserId(),null);
                    }
                }
                SysUser sysUser = userMap.get(vo.getInspectionUserId());
                if(sysUser != null){
                    vo.setInspectionUserPhone(sysUser.getPhonenumber());
                    vo.setInspectionUserName(sysUser.getNickName());
                }
            }
            vos.add(vo);
        }
        // List<InspectionInfoVo> vos = new ArrayList<>();


        return getDataTable(vos);
    }


    @PostMapping("/distributeInspector")
    @ApiOperation("分配巡查人员")
    public AjaxResult distributeInspector(@RequestParam("inspectionId") Long inspectionId, @RequestParam("inspectionUserId") Long inspectionUserId) {
        inspectionService.update(new UpdateWrapper<Inspection>().eq(Inspection.INSPECTION_ID, inspectionId).set(Inspection.INSPECTION_USER_ID, inspectionUserId));
        return AjaxResult.success();
    }

    @GetMapping("/getMyInspectionList")
    @ApiOperation("获取我的巡检工单")
    public R<List<InspectionInfoVo>> getMyInspectionList(@ApiParam(name = "status", value = "状态，0为处理，1处理") Integer status) {
        //只查用户的巡检工单信息
        Long userId = SecurityUtils.getUserId();
        Inspection inspection = new Inspection();
        inspection.setInspectionUserId(userId);
        inspection.setStatus(status);
        TableDataInfo inspectionList = getInspectionList(inspection);
        List<InspectionInfoVo> vos = (List<InspectionInfoVo>) inspectionList.getData();

        return R.ok(vos==null?new ArrayList<>():vos);
    }

    @GetMapping("/getInspectionDetail")
    @ApiOperation("获取巡检工单详情或处理结果")
    public R<InspectionInfoVo> getInspectionDetail(@ApiParam(name="inspectionId",value = "巡检工单信息主键")Long inspectionId) {
        Inspection inspection = new Inspection();
        inspection.setInspectionId(inspectionId);
        TableDataInfo inspectionList = getInspectionList(inspection);
        InspectionInfoVo inspectionInfoVo = (InspectionInfoVo) inspectionList.getData().get(0);
        return R.ok(inspectionInfoVo);
    }

    @PostMapping("/resolveInspection")
    @ApiOperation("巡查人员填写巡查结果，返回的提示数据超过6个")
    public AjaxResult resolveInspection(@RequestBody ResolveInspectionVo vo) {
        //二维码丢失时绑定二维码
        //巡检结果类型(0：正常，1：设备故障，2：设备漏绑，3：安装位置码缺失，4：其他)
        //填写故障时生成故障信息返回故障主键，故障信息包括故障的几个处理阶段
        Inspection inspection = inspectionService.getById(vo.getInspectionId());
        BeanUtils.copyProperties(vo, inspection);
        Integer resultType = inspection.getResultType();
        InspectionTask task = inspectionTaskService.getById(inspection.getInspectionTaskId());
        R<AmsOwnAddress> rAddressInfo = ownAddressController.getInfoR(inspection.getAddressId());
        if (R.FAIL == rAddressInfo.getCode()) {
            throw new ServiceException(rAddressInfo.getMsg());
        }
        switch (resultType) {
            case 0:
                break;
            case 1:
                //生成故障表数据
                AsmsFault fault = new AsmsFault();
                fault.setFaultFindUserId(SecurityUtils.getUserId());
                fault.setAddressId(vo.getAddressId());
                fault.setCreateBy(SecurityUtils.getUsername());
                fault.setCreateTime(System.currentTimeMillis());
                fault.setRemark("巡检处理故障！");
                asmsFaultService.save(fault);
                inspection.setFaultId(fault.getFaultId());
                //生成故障资产表数据
                AsmsFaultAsset faultAsset = new AsmsFaultAsset();
                faultAsset.setFaultId(fault.getFaultId());
                faultAsset.setAssetFaultTypeId(vo.getAssetFaultReasonId());
                faultAsset.setCreateBy(SecurityUtils.getUsername());
                faultAsset.setDescription(vo.getInspectionInfo());
                faultAsset.setCreateTime(System.currentTimeMillis());
                AsmsAssetFullInfo fullInfo = asmsAssetFullInfoService.getOne(new QueryWrapper<AsmsAssetFullInfo>().eq(AsmsAssetFullInfo.ASSET_ID, inspection.getAssetId()));
                BeanUtils.copyProperties(fullInfo, faultAsset);
                faultAsset.setMaintenanceDeptId(SecurityUtils.getDeptId());
                faultAsset.setMaintenanceDeptAncestors(tokenService.getLoginUser().getSysDept().getAncestors());
                faultAsset.setOwnDeptId(inspection.getOwnDeptId());
                faultAsset.setDescriptionImages(vo.getImages());
                faultAsset.setIsFinish(0);
                faultAsset.setStage(5);

                asmsFaultAssetService.save(faultAsset);

                final CompletableFuture<Boolean> task1 = CompletableFuture.supplyAsync(() -> {
                    //报修初始阶段
                    AsmsFaultReportStage reportStage = new AsmsFaultReportStage();
                    reportStage.setFaultAssetId(faultAsset.getFaultAssetId());
                    reportStage.setStartTime(System.currentTimeMillis());
                    reportStage.setEndTime(System.currentTimeMillis());
                    reportStage.setStatus(1);
                    reportStage.setReason("维护方巡检时处理故障");
                    //reportStage.setOwnChargeUserId(SecurityUtils.getUserId());
                    reportStage.setOwnChargeDeptId(inspection.getOwnDeptId());
                    asmsFaultReportStageService.save(reportStage);
                    return true;
                });
                final CompletableFuture<Boolean> task2 = CompletableFuture.supplyAsync(() -> {
                    //生成故障派单阶段信息
                    AsmsFaultDispatchStage dispatchStage = new AsmsFaultDispatchStage();
                    dispatchStage.setFaultAssetId(faultAsset.getFaultAssetId());
                    dispatchStage.setMaintenanceChargeUserId(task.getChargeUserId());
                    dispatchStage.setMaintenanceDeptId(task.getMaintenanceDeptId());
                    dispatchStage.setEndTime(System.currentTimeMillis());
                    dispatchStage.setStatus(1);
                    dispatchStage.setStartTime(System.currentTimeMillis());
                    asmsFaultDispatchStageService.save(dispatchStage);
                    return true;
                });

                    //生成故障处理阶段信息
                    AsmsFaultResolveStage resolveStage =new AsmsFaultResolveStage();
                    resolveStage.setMaintenanceDeptId(task.getMaintenanceDeptId());
                    resolveStage.setFaultResolveUserId(SecurityUtils.getUserId());
                    resolveStage.setFaultAssetId(faultAsset.getFaultAssetId());
                    BeanUtils.copyProperties(vo,resolveStage);
                    resolveStage.setStartTime(System.currentTimeMillis());
                    resolveStage.setEndTime(System.currentTimeMillis());
                    resolveStage.setStatus(1);
                    asmsFaultResolveStageService.save(resolveStage);
                    AsmsFaultResolveFaultVo resolveFaultVo =new AsmsFaultResolveFaultVo();
                    BeanUtils.copyProperties(resolveStage,resolveFaultVo);
                    resolveFaultVo.setRepairName(SecurityUtils.getUsername());
                    resolveFaultVo.setRepairPhone(tokenService.getLoginUser().getSysUser().getPhonenumber());
                    resolveFaultVo.setAssetTypeName(fullInfo.getAssetTypeName());
                    resolveFaultVo.setFaultDescription(vo.getInspectionInfo());
                    asyncService.sendResolveWxSubscribeMsg(resolveFaultVo);

                final CompletableFuture<Boolean> task4 = CompletableFuture.supplyAsync(() -> {
                    //生成故障处理阶段信息
                    AsmsFaultConfirmStage confirmStage =new AsmsFaultConfirmStage();
                    confirmStage.setFaultAssetId(faultAsset.getFaultAssetId());
                    confirmStage.setStatus(0);
                    confirmStage.setStartTime(System.currentTimeMillis());
                    asmsFaultConfirmStageService.save(confirmStage);
                    return true;
                });
                break;
            case 3:
                if (StringUtils.isEmpty(vo.getCode())) {
                    return AjaxResult.error("安装位置码缺失时应有新的位置码信息！");
                } else {

                    AsmsOwnAddressAssetCode code = new AsmsOwnAddressAssetCode();
                    code.setAddressId(inspection.getAddressId());
                    code.setCode(vo.getCode());
                    code.setDeptId(rAddressInfo.getData().getDeptId());
                    code.setCreateBy(SecurityUtils.getUsername());
                    code.setCreateTime(System.currentTimeMillis());
                    code.setRemark("巡检位置码缺失时贴的新码");
                    try {
                        asmsOwnAddressAssetCodeService.save(code);
                    } catch (Exception e) {
                        return AjaxResult.error("安装位置码已使用，请更换！");
                    }
                }
                break;
        }
        inspection.setStatus(1);
        inspection.setEndTime(System.currentTimeMillis());
        inspectionService.updateById(inspection);
        asyncService.sendInspectionResultWxSubscribeMsg(vo,task.getChargeUserId(),tokenService.getLoginUser(),rAddressInfo.getData().getFullName());
        return AjaxResult.success();
    }
    @ApiOperation("保存用户的轨迹信息")
    @PostMapping("/saveTrajectory")
    public AjaxResult saveTrajectory(@RequestBody SaveTrajectoryVo vo){
        List<SaveTrajectoryVo> vos =new ArrayList<>();
        Inspection inspection =inspectionService.getById(vo.getInspectionId());
        if(StringUtils.isNotEmpty(inspection.getTrajectory())){
            vos.addAll(JSONArray.parseArray(inspection.getTrajectory(), SaveTrajectoryVo.class));
        }

        vos.add(vo);
        inspection.setTrajectory(JSONArray.toJSONString(vos));
        inspectionService.updateById(inspection);
        return success();
    }
    @ApiOperation("修改轨迹记录状态")
    @GetMapping("/changeTrajectoryStatus")
    public AjaxResult changeTrajectoryStatus(@RequestParam("inspectionId") Long inspectionId, @RequestParam("locationState") Integer locationState){
        inspectionService.update(new UpdateWrapper<Inspection>().eq(Inspection.INSPECTION_ID,inspectionId).set(Inspection.LOCATION_STATE,locationState));
        return success();
    }

    @ApiOperation("修改轨迹记录状态")
    @GetMapping("/exportInspectionExcel")
    public void exportInspectionExcel(HttpServletResponse response,Long taskId,Long deptId,Long inspectionTime) throws IOException {

        InspectionExcelUtil inspectionExcelUtil = new InspectionExcelUtil();

        InspectionReportVo vo = new InspectionReportVo();
        vo.setTitle("设备巡检报告");

        vo.setInspectionDeptName(tokenService.getLoginUser().getSysDept().getDeptFullName());

        R<SysDept> rDept = deptController.getDeptById(deptId);
        if (rDept.getCode() == R.FAIL) {
            throw new ServiceException(rDept.getMsg());
        }

        if (rDept.getData() == null) {
            throw new IllegalStateException("can`t found deptId");
        }

        vo.setCustomerDeptName(rDept.getData().getDeptFullName());

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd");
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(inspectionTime), ZoneOffset.systemDefault());
        vo.setInspectionTime(localDateTime.format(formatter));

        vo.setInspectionUserName(SecurityUtils.getUsername());

        R<SysUser> rUser = userController.getUserByIdR(SecurityUtils.getUserId());
        if (rUser.getCode() == R.FAIL) {
            throw new ServiceException(rUser.getMsg());
        }
        vo.setInspectionUserPhone(rUser.getData().getPhonenumber());


        List<Inspection> list = inspectionService.list(new QueryWrapper<Inspection>().eq(Inspection.INSPECTION_TASK_ID, taskId).eq(Inspection.OWN_DEPT_ID, deptId).eq(Inspection.STATUS,1));
        if(list.size() <= 0){
            throw new IllegalStateException("找不到相关巡检记录");
        }

        Long[] assetIds = new Long[list.size()];
        for(int i = 0;i<list.size();i++){
           assetIds[i] = list.get(i).getAssetId();
        }


        List<AsmsAssetFullInfo> fullInfoList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>().in(AsmsAssetFullInfo.ASSET_ID, assetIds));
        Map<String,Integer> res = new HashMap<>();
        Map<String,Integer> err = new HashMap<>();
        StringBuilder errInfo = new StringBuilder("");
        Map<Long,StringBuilder> errMap = new HashMap<>();
        for(Inspection inspection : list){
            for(AsmsAssetFullInfo fullInfo : fullInfoList) {
                if(inspection.getAssetId().equals(fullInfo.getAssetId())){
                    if (res.containsKey(fullInfo.getAssetTypeName())) {
                        res.put(fullInfo.getAssetTypeName(),res.get(fullInfo.getAssetTypeName())+1);
                    }else{
                        res.put(fullInfo.getAssetTypeName(),1);
                    }

                    if (inspection.getResultType() == 1) {
                        if (err.containsKey(fullInfo.getAssetTypeName())){
                            err.put(fullInfo.getAssetTypeName(),err.get(fullInfo.getAssetTypeName())+1);
                        }else{
                            err.put(fullInfo.getAssetTypeName(),1);
                        }

                        StringBuilder temInfo = new StringBuilder();
                        errMap.put(inspection.getFaultId(),temInfo);
                        temInfo.append(fullInfo.getAddressFullName());
                        temInfo.append(",");
                        temInfo.append(fullInfo.getAssetTypeName());
                        temInfo.append(",");
                    }
                }

            }

        }

        List<AsmsFaultResolveStage> asmsFaultResolveStages = asmsFaultResolveStageService.
                selectFaultResolveStageByFaultIds(errMap.keySet().toArray(new Long[errMap.keySet().size()]));

        for(AsmsFaultResolveStage resolve :asmsFaultResolveStages){
            if(errMap.get(resolve.getAssetFaultReasonId()) != null){
                errInfo.append(errMap.get(resolve.getAssetFaultReasonId()));
                if(resolve.getAssetFaultReason() != null){
                    errInfo.append(resolve.getAssetFaultReason());
                }else{
                    errInfo.append("无");
                }

                errInfo.append(",");
                errInfo.append(resolve.getAssetFaultSolution());
                errInfo.append(";");
                errInfo.append("\n");
            }
        }

        Integer total = 0;
        Integer errNum = 0;

        List<InspectionReportVo.InspectionResult> results = new LinkedList<>();

        Iterator<String> iterator = res.keySet().iterator();
        while(iterator.hasNext()){
            InspectionReportVo.InspectionResult result = new InspectionReportVo.InspectionResult();
            String assetTypeName = iterator.next();
            result.setAssetTypeName(assetTypeName);
            result.setTotal(res.get(assetTypeName));
            result.setUnNormalNumber(err.get(assetTypeName));
            if(err.containsKey(assetTypeName)){
                result.setNormalNumber(res.get(assetTypeName)-err.get(assetTypeName));
                errNum = errNum + err.get(assetTypeName);
            }else{
                result.setNormalNumber(res.get(assetTypeName));
                result.setUnNormalNumber(0);
            }
            results.add(result);

            total = total + res.get(assetTypeName);

        }

        vo.setContent(results);

        StringBuilder summary = new StringBuilder();
        summary.append("1、总体情况：\n");
        summary.append("本次巡检设备总数为:");
        summary.append(total);
        summary.append("，其中正常的数量为:");
        summary.append(total - errNum);
        summary.append("，其中异常的数量为:");
        summary.append(errNum);
        summary.append("\n2、异常处理情况：\n");
        if(errInfo.length() == 0){
            errInfo.append("无");
        }

        summary.append(errInfo.toString());

        vo.setSummary(summary.toString());

        inspectionExcelUtil.exportInspectionExcel(response,vo,"设备巡检报告");

    }


}
